Skip to content
lab components / Forms and input

Form

A container that collects and submits user input through various interactive elements.

This is a Lab component!

That means it doesn't satisfy our definition of done and may be changed or even deleted. For an exact status, please reach out to the Fancy team through the dev_fancy or ux_fancy channels.

import { Form } from "@siteimprove/fancylab";

#Examples

#Basic Usage

A form is a group of related input controls that allows users to provide data or configure options. When using the Form component, be sure to wrap your input controls with the Form Element Wrapper component to get consistent styling and access to features like label, help and error messages, invalid and disabled states, etc.

These elements typically include:

  • Labels: Clearly identify each input field's purpose with concise, descriptive labels. Position labels left aligned and above the input field by default for better readability and accessibility.
  • Data Inputs: Include various structured input types like Input Field , Checkbox , Radios , Select, Period Picker, etc. Check the individual component guidelines for specific usage recommendations.
  • Help Text: Provide contextual guidance (e.g., tooltips, placeholders, helper text) to assist users in providing the correct information. Place help text near the relevant input field for easy reference.
  • Action Bar: Enable users to take action, such as submitting the form or resetting input values. Include primary and secondary action buttons as needed.

Form heading

const [value, setValue] = useState(""); const [value1, setValue1] = useState(""); const onCancel = () => { setValue(""); setValue1(""); }; const onSubmit = (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); alert("submitting"); }; return ( <> <Form heading="Form heading" onSubmit={onSubmit}> <FormElementWrapper name="Basic input" label="Basic label"> <InputField aria-label="My accessible input component" placeholder="Placeholder" value={value} onChange={setValue} /> </FormElementWrapper> <FormElementWrapper name="Basic text area" label="Basic label"> <TextArea aria-label="My accessible textarea component" value={value1} onChange={setValue1} /> </FormElementWrapper> <ActionBar primary={{ children: "Save", type: "submit", }} cancel={{ children: "Cancel", type: "reset", onClick: onCancel }} noPadding noBackground /> </Form> </> );

#Submit Form Example

Enhance the basic form with designated areas for submit. If possible, always include a "Cancel" button for users to exit.

Form heading

const [value, setValue] = useState(""); const [value1, setValue1] = useState(""); const onSubmit = (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); alert("submitting"); }; return ( <Form heading="Form heading" onSubmit={onSubmit}> <FormElementWrapper name="Basic input" label="Basic label"> <InputField aria-label="My accessible input component" placeholder="Placeholder" value={value} onChange={setValue} /> </FormElementWrapper> <FormElementWrapper name="Basic text area" label="Basic label"> <TextArea aria-label="My accessible textarea component" value={value1} onChange={setValue1} /> </FormElementWrapper> <ActionBar primary={{ children: "Primary", type: "submit", }} noPadding noBackground /> </Form> );

#Submit Form - Slim Example

A more compact version of the Submit Form, ideal for limited space (e.g Modal) or when the form has fewer fields.

Form heading

const [value, setValue] = useState(""); const [value1, setValue1] = useState(""); const onSubmit = (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); alert("submitting"); }; return ( <Form variant="slim" heading="Form heading" onSubmit={onSubmit}> <FormElementWrapper name="Basic input" label="Basic label"> <InputField aria-label="My accessible input component" placeholder="Placeholder" value={value} onChange={setValue} /> </FormElementWrapper> <FormElementWrapper name="Basic text area" label="Basic label"> <TextArea aria-label="My accessible textarea component" value={value1} onChange={setValue1} /> </FormElementWrapper> <ActionBar primary={{ children: "Primary", type: "submit", }} noPadding noBackground /> </Form> );

#Submit Form - Horizontal Example

Optimizes readability by aligning labels horizontally alongside the corresponding input fields. This layout is particularly useful for forms with shorter labels or when space is constrained.

Form heading

const [value, setValue] = useState(""); const [value1, setValue1] = useState(""); const onSubmit = (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); alert("submitting"); }; return ( <Form variant="horizontal" heading="Form heading" onSubmit={onSubmit}> <FormElementWrapper name="Basic input" label="Basic label"> <InputField aria-label="My accessible input component" placeholder="Placeholder" value={value} onChange={setValue} /> </FormElementWrapper> <FormElementWrapper name="Basic text area" label="Basic label"> <TextArea aria-label="My accessible textarea component" value={value1} onChange={setValue1} /> </FormElementWrapper> <ActionBar primary={{ children: "Primary", type: "submit", }} noPadding noBackground /> </Form> );

#Properties

PropertyDescriptionDefinedValue
idOptional
stringId applied to the form
childrenOptional
elementElements to be displayed inside the form
headingOptional
stringThe heading for the form
invalidOptional
booleanIs the form in an invalid state
errorsOptional
string[]Error descriptions for describing the invalid state of the form
hideErrorListOptional
booleanShould the error descriptions be hidden
variantOptional
"horizontal" | "regular" | "slim"Form styling options
onSubmitOptional
functionCallback for onSubmit event
data-componentOptional
stringName of the component. Should only be set by components since it needs to stable. Used to track component usage
classNameOptional
stringCustom className that's applied to the outermost element (only intended for special cases)
styleOptional
objectStyle object to apply custom inline styles (only intended for special cases)
data-observe-keyOptional
stringUnique string, used by external script e.g. for event tracking

#Guidelines

#Best practices

#General

Use Form when

  • Collecting multiple pieces of user data or configuring multiple options.
  • A structured, standardized approach to input collection is desired.

#Placement

Form is typically used in the following places:

  • Card (Main content area): Typically used as the central focus of a page or section.
  • Modal: Effective for collecting focused information without disrupting the main content flow.

#Style

  • Siteimprove Design System: Adhere to Siteimprove's guidelines for color, typography, and spacing. If you are not using a component from Fancy, match the styling of your Form to existing components for visual consistency.
  • Optional vs. Mandatory:
    • Clearly indicate required fields with "(required)" or an asterisk (*).
    • If most fields are optional, only mark required fields. If most are required, mark optional fields.
  • Grouping & Alignment:
    • Group related fields together (e.g., name, address).
    • Align the left edges of input fields for a clean visual flow.
  • Length:
    • Keep forms concise and focused on essential information.
    • For long forms, consider using progressive disclosure (show/hide sections as needed).

#Interaction

  • User Control:
    • Always include a "Cancel" button for modal forms or a clear way to exit/discard changes.
    • Support "Undo" and "Redo" functionality if applicable.
  • Clear Labeling and Help Text:
    • Use descriptive labels and avoid relying solely on placeholder text.
    • Provide clear instructions and inline help if needed.
    • Avoid excessive placeholder texts.
  • Validation and Feedback:
    • Validate input in real-time if possible.
    • Provide clear and specific error messages near the relevant fields.
    • Use visual cues (e.g., icons, colors) to indicate the status of each field (valid, invalid, etc.).
  • Form submission and error handling:
    • Review before submission: Allow users to review their input before submitting to minimize errors.
    • Clear feedback: Use visual cues or messages (e.g., Toast) to indicate successful completion or errors during submission.

#Do not use when

  • You have a simple input with minimal validation. Use Input Field instead.
  • You want more control over the styling. If you need complete control over the look and feel of your form, you might prefer using individual input elements and styling them yourself.
  • You're not submitting data to a server. If you're only collecting data for client-side use and don't need to send it to a server, a Form component might not be necessary.

#Accessibility

#For designers

  • Label Placement: Place labels close to their associated input fields. Avoid large gaps, especially in horizontal layouts, as this can confuse users of screen readers and those with visual impairments.
  • Screen Reader Focus: Remember that screen readers primarily focus on the text within the active input field. Ensure clear and accurate labels so users understand the context without relying on surrounding text.

#For developers

This component comes with built-in accessibility, no extra work required.

Explore detailed guidelines for this component: Accessibility Specifications

#Writing

  • Use sentence case for labels, instructions, and error messages.
  • Keep labels brief (1-3 words) but descriptive enough to convey the purpose of the field.
  • Provide clear and concise instructions or help text to guide users.
  • Write informative error messages that clearly explain the issue and how to correct.